package com.ruoyi.common.utils.barcode;

import com.spire.barcode.BarCodeGenerator;
import com.spire.barcode.BarCodeType;
import com.spire.barcode.BarcodeScanner;
import com.spire.barcode.BarcodeSettings;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.print.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import static java.awt.print.Printable.PAGE_EXISTS;

/**
 * 使用spire.barcode生成条形码
 *
 * @author yinjc
 */
@Slf4j
public class SpireBarcodeUtils {

    /**
     * 生成条形码的png图片文件
     * @param msg
     * @param path
     * @param barCodeType
     * @throws IOException
     */
    static void generateBarcode(String msg, String path, BarCodeType barCodeType) throws IOException {
        //保存条码为PNG图片
        ImageIO.write(getBarcodeImage(msg, barCodeType, 150f, 250f), "png", new File(path));
    }


    /**
     * 获取生成的图片的bufferImage
     * @param msg
     * @return
     */
    static BufferedImage getBarcodeImage(String msg, BarCodeType barCodeType, Float imageHeight, Float imageWidth) {
        //创建BarcodeSettings实例
        BarcodeSettings settings = new BarcodeSettings();
        //指定条码类型 BarCodeType.Code_128
        settings.setType(barCodeType);
        //设置条码数据
        settings.setData(msg);
        //设置条码显示数据
        settings.setData2D(msg);
        //显示数据文本
        settings.setShowText(true);
        //设置数据文本显示在条码底部
        settings.setShowTextOnBottom(true);
        //设置黑白条宽度
        settings.setX(0.5f);
        //设置生成的条码图片高度
        settings.setImageHeight(imageHeight);
        //设置生成的条码图片宽度
        settings.setImageWidth(imageWidth);
        //设置边框可见
        settings.hasBorder(false);
        //设置条码边框颜色
        settings.setBorderColor(new Color(0, 0, 0));
        //设置条码边框宽度
        settings.setBorderWidth(0.5f);
//        settings.setBackColor(new Color(133, 218, 152));//设置条码背景色
        //创建BarCodeGenerator实例
        BarCodeGenerator barCodeGenerator = new BarCodeGenerator(settings);
        //根据settings生成图像数据，保存至BufferedImage实例
        return barCodeGenerator.generateImage();
    }

    static String getBarcode(String path, BarCodeType barCodeType) throws Exception {
        //使用scan方法从图片中识别Code 128条形码
        String[] datas = BarcodeScanner.scan(path, barCodeType);
        return datas[0];
    }

    /**
     * 打印条条形码
     * @param bufferedImage
     * @param pageWidth
     * @param pageHeight
     * @param showWidth
     * @param showHeight
     */
    static void barCodePrint(BufferedImage bufferedImage, int pageWidth, int pageHeight, int showWidth, int showHeight) {
        // 通俗理解就是书、文档
        Book book = new Book();
        // 设置成竖打
        PageFormat pf = new PageFormat();
        pf.setOrientation(PageFormat.PORTRAIT);
        // 通过Paper设置页面的空白边距和可打印区域。必须与实际打印纸张大小相符。
        Paper paper = new Paper();
        //纸张大小
        paper.setSize(pageWidth, pageHeight);
        paper.setImageableArea(0, 0, pageWidth, pageHeight);
        pf.setPaper(paper);
        // 把 PageFormat 和 Printable 添加到书中，组成一个页面
        book.append((graphics, pageFormat, pageIndex) -> {
            //将图片绘制到graphics对象中（为什么把需要打印的内容drawImage就可以实现打印自己取看值传递一引用传递的区别）
            graphics.drawImage(bufferedImage, 10, 10, showWidth, showHeight, null);
            return PAGE_EXISTS;//返回0（PAGE_EXISTS）则执行打印，返回1（NO_SUCH_PAGE）则不执行打印
        }, pf);
        // 获取打印服务对象
        PrinterJob job = PrinterJob.getPrinterJob();
        // 设置打印类
        job.setPageable(book);
        try {
            //可以用printDialog显示打印对话框，在用户确认后打印；也可以直接打印
//            job.printDialog();
            job.print();
        } catch (PrinterException e) {
            log.error("调用打印出错，错误信息为：{{}}", e.getMessage());
        }
    }

    /**
     * 打印小标签
     * @param msg
     * @param barCodeType
     */
    public static void printSmallSign(String msg,  BarCodeType barCodeType) {
        float imageHeight = 70;
        float imageWidth = 140;
        BufferedImage bufferedImage = getBarcodeImage(msg, barCodeType, imageHeight, imageWidth);

        // 默认为A4纸张，对应像素宽和高分别为 595, 842
        int pageWidth = 595;
        int pageHeight = 842;
        int showWidth = 140;
        int showHeight = 70;
        barCodePrint(bufferedImage, pageWidth, pageHeight, showWidth, showHeight);
    }

    /**
     * 打印大标签
     * @param msg
     * @param barCodeType
     */
    public static void printBigSign(String msg,  BarCodeType barCodeType) {
        float imageHeight = 150;
        float imageWidth = 250;
        BufferedImage bufferedImage = getBarcodeImage(msg, barCodeType, imageHeight, imageWidth);

        // 默认为A4纸张，对应像素宽和高分别为 595, 842
        int pageWidth = 595;
        int pageHeight = 842;
        int showWidth = 250;
        int showHeight = 150;
        barCodePrint(bufferedImage, pageWidth, pageHeight, showWidth, showHeight);
    }

    public static void main(String[] args) throws Exception {
        String path = "D:\\Users\\Desktop\\barcode.png";
        String msg = "150P-210831-130";
        generateBarcode(msg, path, BarCodeType.Code_128);
//        System.out.println(getBarcode(path, BarCodeType.Code_128));

//        java.util.List<String> str = new ArrayList<>();
//        str.add("FMHC21388P");
//        str.add("NBHC23690P");
//        str.add("JIHC22158P");
//        str.forEach(e -> {
//            // 默认为A4纸张，对应像素宽和高分别为 595, 842
//            printBigSign(e, BarCodeType.Code_128);
//        });

    }

}
